package top.codef.secure.config.delegates;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.session.InvalidSessionStrategy;

import com.fasterxml.jackson.databind.ObjectMapper;

import top.codef.secure.components.CerberusSessionInvalidateStratergy;
import top.codef.secure.config.interfaces.CerberusHttpSecurityConfig;
import top.codef.secure.handlers.CerberusSessionInformationExpiredStrategy;
import top.codef.secure.properties.CerberusSessionProperties;

@Configuration
@EnableConfigurationProperties(CerberusSessionProperties.class)
@ConditionalOnProperty(name = "cerberus.secure.rest-header.enabled", havingValue = "false", matchIfMissing = true)
@Order(4)
public class CerberusSessionSecureConfig implements CerberusHttpSecurityConfig {

	@Autowired
	private CerberusSessionProperties cerberusSessionProperties;

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired(required = false)
	private SessionRegistry sessionRegistry;

	private final Log logger = LogFactory.getLog(CerberusSessionSecureConfig.class);

	@Override
	public void secure(HttpSecurity httpSecurity) throws Exception {
		logger.debug("session设置");
		if (cerberusSessionProperties.isEnabled()) {
//			SessionManagementConfigurer<HttpSecurity> sessionconfig =
			httpSecurity.sessionManagement(x -> {
				x.sessionCreationPolicy(cerberusSessionProperties.getSessionCreationPolicy())
						.invalidSessionStrategy(invalidSessionStrategy());
				final var concurrencyControlConfigurer = x.maximumSessions(cerberusSessionProperties.getMaxSession());
				if (sessionRegistry != null)
					concurrencyControlConfigurer.sessionRegistry(sessionRegistry)
							.expiredSessionStrategy(new CerberusSessionInformationExpiredStrategy(objectMapper));
			});
		} else
			httpSecurity.sessionManagement(x -> x.disable());
	}

	@Bean
	public InvalidSessionStrategy invalidSessionStrategy() {
		InvalidSessionStrategy invalidSessionStrategy = new CerberusSessionInvalidateStratergy(
				cerberusSessionProperties.getInvalidateSessionHandle(),
				cerberusSessionProperties.getInvalidateSessionRedirectUrl(), objectMapper);
		return invalidSessionStrategy;
	}
}
